package com.hospital.controller;

import com.google.gson.Gson;
import com.hospital.dao.WardStatusDao;
import com.hospital.dao.impl.WardStatusDaoImpl;
import com.hospital.dao.impl.WardBedPatientDao;
import com.hospital.dao.impl.PatientDao;
import com.hospital.model.DoctorView;
import com.hospital.model.WardStatusView;
import com.hospital.model.WardBedPatient;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 住院管理Servlet
 * 处理患者入院请求，包括查询可用病房、床位信息和办理入院手续
 */
@WebServlet("/admission/*")
public class AdmissionServlet extends HttpServlet {
    /** 病房状态数据访问对象，用于查询病房信息 */
    private WardStatusDao wardStatusDao = new WardStatusDaoImpl();
    
    /** 病房床位患者关联数据访问对象，用于管理床位信息 */
    private WardBedPatientDao wardBedPatientDao = new WardBedPatientDao();
    
    /** 患者数据访问对象，用于处理患者信息 */
    private PatientDao patientDao = new PatientDao();
    
    /** JSON转换工具对象，用于处理JSON数据的序列化和反序列化 */
    private Gson gson = new Gson();

    /** 床位状态：空闲 */
    private static final int BED_STATUS_AVAILABLE = 2;

    /** 路径：楼层 */
    private static final String PATH_FLOORS = "/floors";
    
    /** 路径：病房 */
    private static final String PATH_WARDS = "/wards";
    
    /** 路径：床位 */
    private static final String PATH_BEDS = "/beds";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        resp.setContentType("application/json;charset=UTF-8");
        String pathInfo = req.getPathInfo();
        
        // 获取当前登录的医生信息
        HttpSession session = req.getSession();
        DoctorView doctor = (DoctorView) session.getAttribute("doctor");
        
        if (doctor == null) {
            resp.setStatus(401);
            resp.getWriter().write("{\"error\": \"未登录\"}");
            return;
        }

        try {
            // 获取楼层列表
            if (PATH_FLOORS.equals(pathInfo)) {
                List<Integer> floors = wardStatusDao.findFloorsByDeptId(doctor.getDeptId());
                resp.getWriter().write(gson.toJson(floors));
            }
            // 获取指定楼层的病房列表
            else if (PATH_WARDS.equals(pathInfo)) {
                int floorNum = Integer.parseInt(req.getParameter("floorNum"));
                List<WardStatusView> wards = wardStatusDao.findByDeptIdAndFloor(
                    doctor.getDeptId(), floorNum);
                // 只返回有空床位的病房
                wards = wards.stream()
                    .filter(ward -> ward.getAvailableBeds() > 0)
                    .collect(Collectors.toList());
                resp.getWriter().write(gson.toJson(wards));
            }
            // 获取指定病房的可用床位
            else if (PATH_BEDS.equals(pathInfo)) {
                int wardId = Integer.parseInt(req.getParameter("wardId"));
                List<WardBedPatient> beds = wardBedPatientDao.getWardBedsInfo(wardId);
                // 过滤出空闲的床位
                List<WardBedPatient> availableBeds = beds.stream()
                    .filter(bed -> bed.getBedStatus() == BED_STATUS_AVAILABLE)
                    .collect(Collectors.toList());
                resp.getWriter().write(gson.toJson(availableBeds));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
            resp.setStatus(500);
            if (e.getMessage().contains("Duplicate entry")) {
                resp.getWriter().write("{\"error\": \"数据库错误：该身份证号已存在住院记录\"}");
            } else if (e.getMessage().contains("foreign key")) {
                resp.getWriter().write("{\"error\": \"数据库错误：床位不存在或已被占用\"}");
            } else {
                resp.getWriter().write("{\"error\": \"数据库错误：" + e.getMessage() + "\"}");
            }
        } catch (NumberFormatException e) {
            resp.setStatus(400);
            resp.getWriter().write("{\"error\": \"无效的参数\"}");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        resp.setContentType("application/json;charset=UTF-8");
        req.setCharacterEncoding("UTF-8");
        
        // 获取当前登录的医生信息
        HttpSession session = req.getSession();
        DoctorView doctor = (DoctorView) session.getAttribute("doctor");
        
        if (doctor == null) {
            resp.setStatus(401);
            resp.getWriter().write("{\"error\": \"未登录\"}");
            return;
        }

        try {
            // 获取表单参数
            String patientName = req.getParameter("patientName");
            String patientGender = req.getParameter("patientGender");
            String patientAge = req.getParameter("patientAge");
            String patientIdCard = req.getParameter("patientIdCard");
            String patientPhone = req.getParameter("patientPhone");
            String conditionDesc = req.getParameter("conditionDesc");
            String bedId = req.getParameter("bedId");
            
            // 验证必填字段
            if (patientName == null || patientGender == null || patientAge == null || 
                patientIdCard == null || patientPhone == null || bedId == null ||
                patientName.trim().isEmpty() || patientGender.trim().isEmpty() || 
                patientAge.trim().isEmpty() || patientIdCard.trim().isEmpty() || 
                patientPhone.trim().isEmpty() || bedId.trim().isEmpty()) {
                
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"所有字段都必须填写\"}");
                return;
            }
            
            // 验证身份证号格式
            if (!validateIdCard(patientIdCard)) {
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"身份证号格式不正确\"}");
                return;
            }
            
            // 验证电话号码格式
            if (!validatePhone(patientPhone)) {
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"电话号码格式不正确\"}");
                return;
            }
            
            // 验证年龄是否为数字
            int age;
            try {
                age = Integer.parseInt(patientAge);
                if (age <= 0) {
                    resp.setStatus(400);
                    resp.getWriter().write("{\"error\": \"年龄必须大于0\"}");
                    return;
                }
            } catch (NumberFormatException e) {
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"年龄必须为数字\"}");
                return;
            }
            
            // 验证床位ID是否为数字
            int bedIdNum;
            try {
                bedIdNum = Integer.parseInt(bedId);
            } catch (NumberFormatException e) {
                resp.setStatus(400);
                resp.getWriter().write("{\"error\": \"无效的床位ID\"}");
                return;
            }
            
            // 调用DAO执行入院操作
            boolean success = patientDao.admitPatient(
                patientName,
                patientGender.charAt(0),
                age,
                patientIdCard,
                patientPhone,
                conditionDesc,
                doctor.getDoctorId(),
                bedIdNum
            );
            
            if (success) {
                resp.getWriter().write("{\"message\": \"入院办理成功\"}");
            } else {
                resp.setStatus(500);
                resp.getWriter().write("{\"error\": \"入院办理失败\"}");
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
            resp.setStatus(500);
            if (e.getMessage().contains("Duplicate entry")) {
                resp.getWriter().write("{\"error\": \"数据库错误：该身份证号已存在住院记录\"}");
            } else if (e.getMessage().contains("foreign key")) {
                resp.getWriter().write("{\"error\": \"数据库错误：床位不存在或已被占用\"}");
            } else {
                resp.getWriter().write("{\"error\": \"数据库错误：" + e.getMessage() + "\"}");
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            resp.setStatus(400);
            resp.getWriter().write("{\"error\": \"参数错误：" + e.getMessage() + "\"}");
        } catch (SecurityException e) {
            e.printStackTrace();
            resp.setStatus(403);
            resp.getWriter().write("{\"error\": \"权限错误：" + e.getMessage() + "\"}");
        } catch (IOException e) {
            e.printStackTrace();
            resp.setStatus(500);
            resp.getWriter().write("{\"error\": \"IO错误：" + e.getMessage() + "\"}");
        }
    }
    
    // 验证身份证号格式
    private boolean validateIdCard(String idCard) {
        return idCard != null && idCard.matches("^\\d{17}[0-9X]$");
    }
    
    // 验证电话号码格式
    private boolean validatePhone(String phone) {
        return phone != null && phone.matches("^1[3-9]\\d{9}$");
    }
}
